<?php
/*
	验证码：
	导入待生成验证码信息 ，展示新生成的验证码
	列表展示验证码
	提供接口，check验证码是否有效
	提供接口，改变验证码状态
 */

require_once(APP.'libs'.DS.'util.php');
require_once(APP.'libs'.DS.'system_properties.php');
require_once(APP.'libs'.DS.'php-excel.class.php');

require_once(APP.'models'.DS.'mysql_class.inc');
require_once(APP.'config'.DS.'database.php');

App::import('Vendor','/infolex/rest_wrapper');

class CaptchaController extends AppController{
	var $uses = array(); // I don't know what's this do, but without it, the page can't be shown.

	private $uploadFp;


	function __construct(){/*{{{*/
		parent::__construct();
		$config = new DATABASE_CONFIG;
		if(!($this->db = new Core_Mysql('catpcha', $config->default['host'],3306, $config->default['login'], $config->default['password']))){
			throw new Exception ("Can't connect to database!");
		}
	}/*}}}*/

	function __destruct(){/*{{{*/
		if ($this->uploadFp){
			fclose($this->uploadFp);
		}
	}/*}}}*/

	function importsView(){/*{{{*/
		$this->render(null,'management_layout','/captcha/import');
	}/*}}}*/

	function importsAction(){/*{{{*/
		if(!($product_name = $this->post_str_args('product_name'))){
			$this->set('error_msg', '请填写宝贝名称');
			$this->render(null,'management_layout','/captcha/import');
		}
		if (!$_FILES || !$_FILES['award_info']['tmp_name']){
			$this->set('error_msg', '请上传中奖信息文件');
			$this->render(null,'management_layout','/captcha/import');
	 	}

		$this_luck_id = $this->gen_unique_luckid();

		while($infos = $this->absNextLines($_FILES['award_info'])){
			$this->saveCaptchaInfos($infos, $this_luck_id, $product_name);
		}


		$this->set('this_count', $this->get_this_count($this_luck_id));
		$this->set('this_luck_id', $this_luck_id);
		$this->set('product_name', $product_name);

		$this->render(null,'management_layout','/captcha/import');
	}/*}}}*/

	function downloadLucks($luck_id){/*{{{*/
		if ($luck_id <= 0){
			return false; // 404 ? TODO
		}
		
		if(!($infos = $this->get_captchas_by_luckid($luck_id))){
			return false; // 404 ? TODO
		}

		$filename = 'Captcha_'.$luck_id;
		$tablename = $infos[0]['product_name'].'_'.$luck_id;
		$xls = new Excel_XML('UTF-8', false, $tablename);
		$xls->addArray(array(array(
			'中奖时间',
			'用户名',
			'姓名',
			'电话号码',
			'邮箱',
			'地址',
			'验证码',
			)));
		foreach ($infos as $r){
			$xls->addArray(array(array(
				$r['create_time'],
				$r['user_id'],
				$r['user_name'],
				$r['phone'],
				$r['email'],
				$r['address'],
				$r['code'],
			)));
		}
		$xls->generateXML($filename);
		exit;
	}/*}}}*/

	function listLucks(){/*{{{*/
		$page = $this->get_num_args('page', 1);
		$per_page = 20;

		$q = $this->get_str_args('q');
		if ($q){
			if (iconv('utf-8', 'utf-8', $q) != $q){
				$q = iconv('gbk', 'utf-8', $q);
			}
		}

		$lucks_with_total = $this->get_lucks($page, $per_page, $q);

		$this->set('page', $page);
		$this->set('page_total', ceil($lucks_with_total['total']/$per_page));
		$this->set('total', $lucks_with_total['total']);
		$this->set('info', $lucks_with_total['info']);
		$this->set('url_prefix', $this->make_page_url_prefix(SystemProperties::$app_host.'/captcha/listLucks/?q='.urlencode($q)));
 
		$this->render(null,'management_layout','/captcha/list');
	}/*}}}*/

	private function &absNextLines(array $files, $per_page=1000){/*{{{*/
		$this->openFile($files['tmp_name']);

		$lines = array();
		while(!feof($this->uploadFp) && $per_page){
			if($line=trim(fgets($this->uploadFp))){
				$lines[] = $line;
				--$per_page;
			}
		}

		if ($lines){
			return $this->explodeCsvToCaptchaInfos($lines);
		} else {
			return false;
		}
	}/*}}}*/

	private function openFile($filename){/*{{{*/
		if (!$filename){
			throw new Exception("请指定要打开的文件名");
		}

		if ($this->uploadFp){ // Be careful, one thread can only open one file!!
			return $this->uploadFp;
		}
		if (!$this->uploadFp = fopen($filename, 'r')){
			throw new Exception("无法打开：$filename");
		}
		return $this->uploadFp;
	}/*}}}*/

	private function &explodeCsvToCaptchaInfos(array &$lines){/*{{{*/
		if (!$lines){
			return NULL;
		}

		$infos = array();
		foreach($lines as $l){
			$infos[] = explode(',', iconv('gbk', 'utf-8',$l));
		}

		return $infos;
	}/*}}}*/

	private function post_num_args($arg_name, $def=0){/*{{{*/
		return empty($_POST[$arg_name])? $def: intval($_POST[$arg_name]);
	}
	private function get_num_args($arg_name, $def=0){
		return @isset($_GET[$arg_name])? intval($_GET[$arg_name]): $def;
	}
	private function request_num_args($arg_name, $def=0){
		return empty($_REQUEST[$arg_name])? $def: intval($_REQUEST[$arg_name]);
	}
	private function array_num_args($arg_name, $arr, $def=0){
		return empty($arr[$arg_name])? $def: intval($arr[$arg_name]);
	}
	private function array_str_args($arg_name, $arr, $def=''){
		return empty($arr[$arg_name])? $def: trim($arr[$arg_name]);
	}
	private function post_str_args($arg_name, $def=''){
		return empty($_POST[$arg_name])? $def: trim($_POST[$arg_name]);
	}
	private function get_str_args($arg_name, $def=''){
		return empty($_GET[$arg_name])? $def: trim($_GET[$arg_name]);
	}
	private function request_str_args($arg_name, $def=''){
		return empty($_REQUEST[$arg_name])? $def: trim($_REQUEST[$arg_name]);
	}/*}}}*/

	// Just an alias to mysql_real_escape_string
	private function _es($string){/*{{{*/
		return mysql_real_escape_string($string);
	}/*}}}*/

	// Only generate code with littel alpha and number
	private function genCaptcha($alpha_len, $num_len){/*{{{*/
		if ($alpha_len <= 0 && $num_len <= 0){
			return null;
		}
		$alpha_pool = 'qwertyuiopasdfghjklzxcvbnm';
		$number_pool = '0123456789';
		$alpha_pool_len = strlen($alpha_pool)-1;
		$number_pool_len = strlen($number_pool)-1;

		$captcha = '';
		if ($alpha_len > 0){
			for($i=0; $i<$alpha_len; ++$i){
				$captcha .= $alpha_pool[mt_rand(0, $alpha_pool_len)];
			}
		}
		if ($num_len > 0){
			for($i=0; $i<$num_len; ++$i){
				$captcha .= $number_pool[mt_rand(0, $number_pool_len)];
			}
		}

		return $captcha;
	}/*}}}*/

	private function saveCaptchaInfos(array &$infos, $this_luck_id, $product_name){/*{{{*/
		if (!$infos){
			return false;
		}
		$this_luck_id = intval($this_luck_id);
		$product_name = $this->_es($product_name);

		$sql = "insert ignore into g_luckcaptcha (user_id, product_name, main_type, platform, code, status, create_time, apply_time, user_name, phone, luck_id, address, province, city, zipcode, birthday, email) values ";

		foreach($infos as $i){
			$time = str_replace('"','',$i[6]);
			if (!strtotime($time)){
				continue;
			}
 
			$code = 'bg'.$this->genCaptcha(4, 4);
			$sql .= sprintf("('%s', '%s', 'bg', 'bg', '%s', 'active', '%s', '', '%s', '%s', %d, '%s', '', '', '', '', '%s'),",
				$this->_es($i[0]),
				$product_name,
				$code, 
				$this->_es($time),
				$this->_es($i[1]),
				$this->_es($i[3]),
				$this_luck_id,
				$this->_es($i[2]),
				$this->_es($i[4])
			);
		}
		$sql = substr($sql, 0, -1);

		if($this->db->update($sql) > 0){
			return $this->db->last_id();
		} else {
			return false;
		}
	}/*}}}*/

	private function gen_unique_luckid(){/*{{{*/
		return time()-1308585600 . $this->genCaptcha(0, 2); // database's luck_id is int(11) ! Be careful !
		/* "2011-06-21" */
	}/*}}}*/

	private function get_this_count($this_luck_id){/*{{{*/
		$sql = sprintf("select count(1) as cnt from g_luckcaptcha where luck_id = %d", intval($this_luck_id));
		$ret = $this->db->query($sql);
		if (!$ret){
			return 0;
		} else {
			return $ret['cnt'];
		}
	}/*}}}*/

	private function get_captchas_by_luckid($luck_id){/*{{{*/
		$sql = sprintf("select * from g_luckcaptcha where luck_id = %d", intval($luck_id));
		return $this->db->querys($sql);
	}/*}}}*/

	private function get_lucks($page, $per_page, $kw=null){/*{{{*/
		if ($page <= 0 || $per_page <= 0){
			return false;
		}

		$extra = null;
		if ($kw){
			$extra .= sprintf(" and product_name like '%%%s%%' ", $this->_es($kw));
		}

		$sql = sprintf("select SQL_CALC_FOUND_ROWS product_name, luck_id from g_luckcaptcha where 1=1 %s group by luck_id limit %d offset %d",
			$extra,
			intval($per_page),
			($page - 1)*$per_page
		);

		return $this->db->querys_total($sql);
	}/*}}}*/

	static function pager($page_total, $cur_page, $url_prefix, $show=4){/*{{{*/
		if(empty($page_total) || empty($url_prefix)){
			return false;
		}

		$html = null;
		
		if ($cur_page > 1){
			$last_page = $cur_page - 1;
			$html .= <<<EOT
			 <a rel="prev" class="prev_page" href="$url_prefix$last_page">« 上一页<span>&nbsp;</span></a> 
EOT;
		}

		if ($show >= $page_total){
			$min_left = 1;
			$max_right = $page_total;
		} else {
			$padding_left = $cur_page - 1;
			$padding_right = $page_total - $cur_page;
			
			$left_show = ceil($show/2);
			$right_show = $show - $left_show;

			if ($padding_left >= $left_show && $padding_right >= $right_show){
				$min_left = $cur_page - $left_show;
				$max_right = $cur_page + $right_show;
			} else if ($padding_left < $left_show && $padding_right >= $right_show){
				$min_left = 1;
				$max_right = $show + $min_left;
			} else {
				$max_right = $page_total;
				$min_left = $max_right - $show;
			}
		}

		for(; $min_left < $cur_page; ++$min_left){
			$html .= <<<EOT
			 <a rel="prev" href="$url_prefix$min_left">$min_left<span>&nbsp;</span></a> 
EOT;
		}

		$html .= <<<EOT
			<span class="current">$cur_page<span>&nbsp;</span></span> 
EOT;

		for($used=$cur_page+1; $used<=$max_right; ++$used){
			$html .= <<<EOT
			 <a rel="next" href="$url_prefix$used">$used<span>&nbsp;</span></a> 
EOT;
		}

		if ($cur_page < $page_total){
			$next_page = $cur_page + 1;
			$html .= <<<EOT
			 <a rel="next" class="next_page" href="$url_prefix$next_page">下一页 »<span>&nbsp;</span></a>
EOT;
		}

		return $html;
	}/*}}}*/

	function make_page_url_prefix($url_prefix){/*{{{*/
		$url_prefix = preg_replace('/\bpage=\d&?(.*)/', '\1', $url_prefix, -1, $replace_count);
		if (strpos($url_prefix, '?') !== false){
			$url_prefix .= '&page=';
		} else {
			$url_prefix .= '?page=';
		}

		return $url_prefix;
	}/*}}}*/
}
